﻿using System;
using System.Collections.Generic;
using System.Data.Common;
using System.Text;
using VipSoft.Core.Driver;
using VipSoft.Core.Entity;

namespace VipSoft.Core.Utility
{
    public class Criteria
    {

        //private Map<String, SqlParameter> parameterMap;
        public IDriver Driver { get; set; }
        public IList<Criterion> CriterionList { get; set; }
        public IDictionary<string, DbParameter> DicParameter { get; set; }
        public IList<DbParameter> DbParameter { get; set; }

        #region Constructor


        public Criteria()
        {
            CriterionList = new List<Criterion>();
        }

        /// <summary>
        /// 添加 = 判断条件。
        /// </summary>
        /// <param name="name">PropertyName</param>
        /// <param name="value">Value</param>
        public Criteria(String name, Object value)
        {
            CriterionList = new List<Criterion>();
            if (value != null)
                AddCriterion(new Criterion(name, OP.EQ, value));
        }

        public Criteria(String name, OP operation, Object value)
        {
            CriterionList = new List<Criterion>();
            if (value != null)
                AddCriterion(new Criterion(name, operation, value));
        }
        #endregion

        #region Public


        public void AddCriterion(Criterion criterion)
        {
            CriterionList.Add(criterion);
        }

        public Criteria Add(Criteria criteria)
        {
            this.AddCriterion(new Criterion(criteria));
            return this;
        }

        public Criteria Add(String name, Object value)
        {
            if (value != null)
                this.AddCriterion(new Criterion(name, value));
            return this;
        }

        public Criteria Add(String name, OP operation, Object value)
        {
            if (value != null)
                this.AddCriterion(new Criterion(name, operation, value));
            return this;
        }

        public Criteria Add(LOP logicOperation, String name, Object value)
        {
            if (value != null)
                this.AddCriterion(new Criterion(logicOperation, name, OP.EQ, value));
            return this;
        }

        public Criteria Add(LOP logicOperation, String name, OP operation, Object value)
        {
            if (value != null)
                this.AddCriterion(new Criterion(logicOperation, name, operation, value));
            return this;
        }

        public Criteria Add(LOP logicOperation, Criteria criteria)
        {
            this.AddCriterion(new Criterion(logicOperation, criteria));
            return this;
        }
        
        private static string GetWhereCaluse(string conditaion)
        {
            if (string.IsNullOrEmpty(conditaion)) return "";

            var where = new StringBuilder();
            var scodetion = conditaion.Split(';');
            for (var i = 0; i < scodetion.Length; i++)
            {
                if (string.IsNullOrEmpty(scodetion[i]) || (scodetion[i].Contains("["))) continue;
                if (where.Length == 0)
                {
                    where.AppendFormat(" {0}", scodetion[i].Replace("AND ", "").Replace("OR ", ""));
                }
                else
                {
                    where.AppendFormat(" {0}", scodetion[i]);
                }
            }
            return where.ToString();
        }

        /// <summary>
        /// 根据条件key得到值
        /// </summary>
        /// <param name="key"></param>
        /// <returns></returns>
        public Object Get(string key)
        {
            foreach (Criterion criterion in CriterionList)
            {
                if (criterion.Name == key)
                {
                    return criterion.Value;
                }
            }
            return string.Empty;
        }

        public string ToSql(ClassMetadata classMetadata)
        {
            /*                 
                    int i = 0;
                    for (Criterion criterion : criteria) {
                        sql.append(criterion.toSql(classMetadata, prefixInSql, i));
                        if (ObjectUtil.isNotEmpty(criterion.getParameterMap())) {
                            parameterMap.putAll(criterion.getParameterMap());
                        }
                        i++;
                    }
                    return sql.toString();
             */
            var result = new StringBuilder();
            var index = 0;
            foreach (var criterion in this.CriterionList)
            {
                criterion.Driver = this.Driver;
                criterion.DicParameter = this.DicParameter;
                criterion.DbParameter = this.DbParameter;
                //if (index > 0)
                //{
                //    result.Append(criterion.LogicOperation == LOP.OR ? " OR " : " AND ");
                //}
                result.Append(criterion.ToSql(classMetadata, index));
                index++;
            }
            return result.ToString();
        }

        #endregion
    }
}
